/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.me.stepapp;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import java.util.List;
import android.graphics.Canvas;
import android.graphics.Point;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.provider.Contacts.People;
import android.view.View;
import android.widget.Toast;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
import com.google.android.maps.Overlay;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 *
 * @author Amber
 */


public class DisplayMap extends MapActivity {
    private static final String MY_LOCATION_CHANGED_ACTION = new String("android.intent.action.LOCATION_CHANGED");
    static final int DISTANCE_RADIUS = 10000000;  // 10.000km
    boolean doUpdates = true;
    MapView mapView = null;
    MapController mapCon = null;
    MapOverlay overlay = null;
    LocationManager locMan = null;
    Location myLoc = null;
    Location fLoc = null;
    ChangeReceiver receiver = null; 
    final IntentFilter filter = new IntentFilter(MY_LOCATION_CHANGED_ACTION);
    MyLocationOverlay whereAmI = null;

    // Array list of all friends
    ArrayList<Friend> allFriends = new ArrayList<Friend>();
    // Array list to store friends
    ArrayList<Friend> nearFriends = new ArrayList<Friend>();


    
    class ChangeReceiver extends BroadcastReceiver {
	@Override
	public void onReceive(Context context, Intent intent) {
            if(doUpdates) {
                updateView();
            }
	}
    }
    
    //  Inner class that handles graphical overlay of locations
    class MapOverlay extends com.google.android.maps.Overlay {
        /*  Draw method to overlay point on the map  */
        @Override
        public void draw(Canvas canvas, MapView mv, boolean shadow) {
            super.draw(canvas, mv, shadow);
            // Point that represents the users current locaton
            Double lat = myLoc.getLatitude() * 1E6;
            Double lng = myLoc.getLongitude() * 1E6;
            GeoPoint point = new GeoPoint(lat.intValue(), lng.intValue());
            // Change to Pixels
            Point screenPts = new Point();
            mapView.getProjection().toPixels(point, screenPts);
            Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.dot);            
            canvas.drawBitmap(bmp, screenPts.x, screenPts.y, null);         
            
            //Locate Friends
            GeoPoint [] fPt = new GeoPoint[nearFriends.size()];
            //Draw each friend with a line pointing to our own location.
            for(int i = 0; i < nearFriends.size(); i++){
                lat = fLoc.getLatitude() * 1E6;
                lng = fLoc.getLongitude() * 1E6;
                fPt[i] = new GeoPoint(lat.intValue(), lng.intValue());
                mapView.getProjection().toPixels(fPt[i], screenPts); 		
                Bitmap fBmp = BitmapFactory.decodeResource(getResources(), R.drawable.pushpin);            
                canvas.drawBitmap(bmp, screenPts.x, screenPts.y, null);
	    }
        }
    }
	
     /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.map);
        mapView = (MapView) findViewById(R.id.mapView);
        mapCon = mapView.getController();
        mapCon.setZoom(15);
        mapView.setBuiltInZoomControls(true);
        mapView.setClickable(true);
        locMan = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
        Location loc = locMan.getLastKnownLocation(LocationManager.GPS_PROVIDER);
	whereAmI = new MyLocationOverlay(this, mapView);
        //loc.getLatitude()
        mapView.getOverlays().add(whereAmI);
	
	updateView();
	autoRefreshGPS();
	refreshList(DISTANCE_RADIUS);
        
        mapView.postInvalidate();
    }

    /* Restart Action */
    @Override
    public void onResume() {
	super.onResume();
	doUpdates = true;
        // Register receiver to receive updates for friends using filter for efficiency
	registerReceiver(receiver, filter);
    }


    @Override
    public void onPause() {
        doUpdates = false;
	unregisterReceiver(receiver);
	super.onPause();
    }

    /* Auto Refresh GPS data abotu current location */
    private void autoRefreshGPS() {
        // Get the first provider available
        List<String> providers = locMan.getAllProviders();
        LocationListener listener = new LocationListener() {
            public void onLocationChanged(Location arg0) {
                if (myLoc != null) {
                    updateView();
                }
                else {
                    Toast.makeText(null, "Location NOT Available", Toast.LENGTH_SHORT);
                }
            }

            public void onStatusChanged(String provider, int status, Bundle extras) {
            }

            public void onProviderEnabled(String provider) {
            }

            public void onProviderDisabled(String provider) {
            }
        };
	locMan.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, listener);

        //BroadcastReceiver instantiated
	receiver = new ChangeReceiver();
	}

    private void refreshList(int radius){
        Cursor c = getContentResolver().query(People.CONTENT_URI, null, null, null, People.NAME + " ASC");
	startManagingCursor(c);
	int notesColumn = c.getColumnIndex(People.NOTES);
	int nameColumn = c.getColumnIndex(People.NAME);

        // Moves the cursor to the first row
	// and returns true if there is sth. to get
	if (c.isFirst()) {
            do {
                String notesString = c.getString(notesColumn);
		Location friendLocation = null;
		if (notesString != null) {
                    // Pattern for extracting geo-ContentURIs from the notes.
                    final String geoPattern = "(geo:[\\-]?[0-9]{1,3}\\.[0-9]{1,6}\\,[\\-]?[0-9]{1,3}\\.[0-9]{1,6}\\#)";
                    // Compile and use regular expression
                    Pattern pattern = Pattern.compile(geoPattern);
                    CharSequence inputStr = notesString;
                    Matcher matcher = pattern.matcher(inputStr);
                    boolean matchFound = matcher.find();
                    if (matchFound) {
                    // We take the first match available
                        String groupStr = matcher.group(0);
			// And parse the Lat/Long-GeoPos-Values from it

			String latid = groupStr.substring(groupStr.indexOf(":") + 1, groupStr.indexOf(","));
			String longit = groupStr.substring(groupStr.indexOf(",") + 1, groupStr.indexOf("#"));
			friendLocation.setLongitude(Float.parseFloat(longit));
			friendLocation.setLatitude(Float.parseFloat(latid));
                    }
                }
		String friendName = c.getString(nameColumn);
		allFriends.add(new Friend(friendLocation, friendName));
		} while (c.isLast() == false);
            }
	}

	private void updateView() {
            // Refresh our gps-location
            myLoc = locMan.getLastKnownLocation(LocationManager.GPS_PROVIDER);
            /* Redraws the mapViee, which also makes our
		 * OverlayController redraw our Circles and Lines */
            
            mapView.invalidate();
	}


    @Override
    protected boolean isLocationDisplayed()  {
        return whereAmI.isMyLocationEnabled();
    }

    @Override
    protected boolean isRouteDisplayed() {
        return false;
    }

        public void clickHandler(View target)  {
        switch(target.getId()){
            case R.id.normal:
                mapView.setSatellite(false);
                mapView.setStreetView(false);
                mapView.setTraffic(false);
                break;
            case R.id.satellite:
                mapView.setSatellite(true);
                break;
            case R.id.street:
                mapView.setStreetView(true);
                break;
            case R.id.traffic:
                mapView.setTraffic(true);
                break;
        }
    }
}

